import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import '../../base/imageres.dart';
import '../../base/log.dart';
import '../../base/theme.dart';
import '../../util/physiological_cycle_count.dart';
import '../../util/string_util.dart';
import '../dashed_horizontal_line.dart';
import '../horizontal_line.dart';
import '../jsw_base_view.dart';

///自定义心率变异性柱状统计图
class DrawHrvBarChart extends StatefulWidget {
  final int menstrualTime;
  final int cycleValue;
  final int menstrualPeriodDays;
  final Map<String, double> barDataMap;
  final Map<String, int> periodDataMap;
  final void Function(double data)? onBarTap;

  const DrawHrvBarChart(
      {super.key,
      required this.menstrualTime,
      required this.cycleValue,
      required this.menstrualPeriodDays,
      required this.barDataMap,
      required this.periodDataMap,
      this.onBarTap});

  @override
  State<StatefulWidget> createState() => _DrawHrvBarChartState();
}

class _DrawHrvBarChartState extends State<DrawHrvBarChart> {
  static const _tag = '[draw_hrv_barchart_widget.dart][_DrawHrvBarChartState]';

  ///近28天的数据
  List<String> _dayDataList = [];

  ///生理周期的值
  var _cycleValue = 0;

  ///最近一次月经的时间戳
  int _menstrualTime = 0;

  ///月经期天数
  var _menstrualPeriodDays = 0;

  ///卵泡期天数
  var _follicularPhaseDays = 0;

  ///易孕期(排卵期)天数(最多十天)
  var _easyPregnancyDays = 0;

  ///黄体期天数
  var _lutealPhaseDays = 13;

  ///是否显示排卵日
  bool _isShowOvulation = false;

  ///排卵日
  DateTime _ovulationDateTime = DateTime.now();

  ///柱状图数据
  List<double> _barDataList = [];

  ///选中的日期
  String _selectDate = "";

  /// 需要添加_maxValue
  double _maxValue = 0.0;

  @override
  void initState() {
    super.initState();
    _menstrualTime = widget.menstrualTime;
    _cycleValue = widget.cycleValue;
    _menstrualPeriodDays = widget.menstrualPeriodDays;
    _dayDataList = _getLastDays(25);
    _barDataList = widget.barDataMap.values.toList();
    if (_barDataList.isNotEmpty) {
      _maxValue = _barDataList.reduce((a, b) => a > b ? a : b);
    }
    if (_maxValue > 150) {
      _maxValue = 200;
    } else if (_maxValue > 100) {
      _maxValue = 150;
    } else if (_maxValue > 50) {
      _maxValue = 100;
    } else if (_maxValue > 100) {
      _maxValue = 150;
    } else if (_maxValue > 50) {
      _maxValue = 100;
    } else if (_maxValue > 0) {
      _maxValue = 50;
    }
    _initCalculationPeriodData();
  }

  List<String> _getLastDays(int num) {
    List<String> dates = [];
    final DateTime now = DateTime.now();
    final DateFormat formatter = DateFormat('yyyy.MM.dd');
    _selectDate = formatter.format(now);
    for (int i = num; i >= 0; i--) {
      DateTime date = now.subtract(Duration(days: i));
      dates.add(formatter.format(date));
    }
    return dates;
  }

  /// 将 yyyy.MM.dd 格式的字符串解析为 DateTime 对象
  DateTime _parseYmdDate(String dateString) {
    try {
      final DateFormat formatter = DateFormat('yyyy.MM.dd');
      return formatter.parse(dateString);
    } catch (e) {
      return DateTime.now();
    }
  }

  ///初始化主界面的周期数据
  void _initCalculationPeriodData() {
    DateTime menstrualDateTime = DateTime.fromMillisecondsSinceEpoch(_menstrualTime);

    final cycleCalculator = CycleCalculator(periodStart: menstrualDateTime, cycleLength: _cycleValue, periodLength: _menstrualPeriodDays);
    final summary = cycleCalculator.summarize();
    Map<String, int> cycleMap = summary.compute();
    _follicularPhaseDays = cycleMap["卵泡期"]!;
    _easyPregnancyDays = cycleMap["易孕前窗"]! +  cycleMap["排卵日"]! +  cycleMap["易孕后窗"]!;
    _lutealPhaseDays = cycleMap["黄体期"]!;
    _isShowOvulation = cycleMap["排卵日"]! == 1;
    _ovulationDateTime = menstrualDateTime.add(Duration(days: _menstrualPeriodDays  + _follicularPhaseDays + (cycleMap["易孕前窗"]!)));

    DartLog.i(_tag,
        '_initCalculationPeriodData 初始化周期天数参数_menstrualTime$_menstrualTime ${DateFormat("yyyy-MM-dd").format(DateTime.fromMillisecondsSinceEpoch(_menstrualTime))} _cycleValue：$_cycleValue _menstrualPeriodDays：$_menstrualPeriodDays _follicularPhaseDays：$_follicularPhaseDays _easyPregnancyDays：$_easyPregnancyDays _lutealPhaseDays：$_lutealPhaseDays  ');

    DartLog.i(_tag,
        '_initCalculationPeriodData 排卵日期 _ovulationDateTime ${DateFormat("yyyy-MM-dd").format(_ovulationDateTime)} distanceDays ${_menstrualPeriodDays  + _follicularPhaseDays + (cycleMap["易孕前窗"]!)}');
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final eachPartWidth = (screenWidth - 50) / 25;
    return Column(
      children: [
        //统计图
        Container(
            width: double.infinity,
            margin:
                const EdgeInsets.only(top: 30, left: 20, right: 20, bottom: 17),
            child: Stack(
              children: [
                Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(
                      height: 12.5,
                      child: Text(
                        "${_maxValue > 0 ? _maxValue.toInt() : 100}",
                        textAlign: TextAlign.left,
                        style: ThemeUtil.p2.copyWith(
                            fontSize: 9,
                            color: const Color(ThemeUtil.primaryWhiteValue50)),
                      ),
                    ),
                    const DashedHorizontalLine(
                      width: double.infinity,
                      height: 0.5,
                      color: Colors.white24,
                      dashLength: 2,
                      dashGap: 2,
                    ),
                    const SizedBox(
                      height: 37.5,
                    ),
                    SizedBox(
                      height: 12.5,
                      child: Text(
                        "${_maxValue > 0 ? (_maxValue * 3 / 4).toInt() : 75} ",
                        textAlign: TextAlign.left,
                        style: ThemeUtil.p2.copyWith(
                            fontSize: 9,
                            color: const Color(ThemeUtil.primaryWhiteValue50)),
                      ),
                    ),
                    const DashedHorizontalLine(
                      width: double.infinity,
                      height: 0.5,
                      color: Colors.white24,
                      dashLength: 2,
                      dashGap: 2,
                    ),
                    const SizedBox(
                      height: 37.5,
                    ),
                    SizedBox(
                      height: 12.5,
                      child: Text(
                        "${_maxValue > 0 ? (_maxValue * 1 / 2).toInt() : 50} ",
                        textAlign: TextAlign.left,
                        style: ThemeUtil.p2.copyWith(
                            fontSize: 9,
                            color: const Color(ThemeUtil.primaryWhiteValue50)),
                      ),
                    ),
                    const DashedHorizontalLine(
                      width: double.infinity,
                      height: 0.5,
                      color: Colors.white24,
                      dashLength: 2,
                      dashGap: 2,
                    ),
                    const SizedBox(
                      height: 37.5,
                    ),
                    SizedBox(
                      height: 12.5,
                      child: Text(
                        "${_maxValue > 0 ? (_maxValue * 1 / 4).toInt() : 25} ",
                        textAlign: TextAlign.left,
                        style: ThemeUtil.p2.copyWith(
                            fontSize: 9,
                            color: const Color(ThemeUtil.primaryWhiteValue50)),
                      ),
                    ),
                    const DashedHorizontalLine(
                      width: double.infinity,
                      height: 0.5,
                      color: Colors.white24,
                      dashLength: 2,
                      dashGap: 2,
                    ),
                    const SizedBox(
                      height: 36.5,
                    ),
                    SizedBox(
                      height: 12.5,
                      child: Text(
                        "0",
                        textAlign: TextAlign.left,
                        style: ThemeUtil.p2.copyWith(
                            fontSize: 9,
                            color: const Color(ThemeUtil.primaryWhiteValue50)),
                      ),
                    ),
                    HorizontalLine(dashedHeight: 1.5, color: Colors.white24),
                  ],
                ),

                //柱状图
                JSWLine(
                  alignment: Alignment.center,
                  clickable: false,
                  margin: const EdgeInsets.only(left: 30.0, top: 14),
                  children: [
                    for (int i = 0; i < _dayDataList.length; i++)
                      _buildDrawHrvBar(
                          data: (widget.barDataMap[_dayDataList[i]] ?? 0) > 200
                              ? 200
                              : (widget.barDataMap[_dayDataList[i]] ?? 0),
                          date: _dayDataList[i],
                          color: _getBarBackgroundColor(
                              _parseYmdDate(_dayDataList[i])))
                  ],
                ),
              ],
            )),

        //是否排卵日
        JSWLine(
          clickable: false,
          margin: const EdgeInsets.only(left: 50.0, top: 1, right: 20),
          children: [
            for (int i = 0; i < _dayDataList.length; i++)
              _buildOvulationDay(
                  isOvulation: _isOvulationDay(_parseYmdDate(_dayDataList[i])))
          ],
        ),

        //柱状颜色说明
        JSWLine(
          margin: const EdgeInsets.only(top: 5, left: 20, right: 20, bottom: 6),
          children: [
            Container(
              width: 30,
              height: 4,
              decoration: BoxDecoration(
                color: Color(
                    _getBarBackgroundColor(_parseYmdDate(_dayDataList[0]))),
                borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(20.0),
                    bottomLeft: Radius.circular(20.0)), // 设
              ),
            ),
            for (int i = 0; i < _dayDataList.length; i++)
              _buildDrawColor(
                  index: i,
                  color: _getBarBackgroundColor(_parseYmdDate(_dayDataList[i])))
          ],
        ),

        //日期
        JSWLine(
          clickable: false,
          margin: const EdgeInsets.only(left: 50.0, top: 1, right: 20),
          children: [
            for (int i = 0; i < _dayDataList.length; i++)
              _buildDrawDate(
                  date: i % 2 == 0
                      ? _parseYmdDate(_dayDataList[i]).day.toString()
                      : "")
          ],
        ),

        //月份
        Container(
          margin: const EdgeInsets.only(top: 2, right: 20),
          child: Row(
            children: [
              Container(
                alignment: Alignment.centerRight,
                width: 50,
                child: Text(
                  StringUtil.getTodayMonth(
                      _parseYmdDate(_dayDataList[0]).month),
                  textAlign: TextAlign.left,
                  style: ThemeUtil.p2.copyWith(fontSize: 10),
                ),
              ),
              SizedBox(
                width: ((_getDifferentMonthIndex()) * eachPartWidth - 50 + eachPartWidth / 2) > 0 ? ((_getDifferentMonthIndex()) * eachPartWidth - 50 + eachPartWidth / 2) : 0,
              ),
              Container(
                alignment: Alignment.center,
                width: 50,
                child: Text(
                  _getDifferentMonth(),
                  style: ThemeUtil.p2.copyWith(fontSize: 10),
                ),
              ),
            ],
          ),
        )
      ],
    );
  }

  ///构建柱状
  Widget _buildDrawHrvBar(
      {required double data, required String date, required int color}) {
    return BaseViewItem(
        weight: 1,
        child: SizedBox(
            width: double.infinity,
            height: 200,
            child: GestureDetector(
              behavior: HitTestBehavior.translucent,
              onTap: () {
                DartLog.i(_tag, '_DrawHrvBarChartState 已经点击:$date');
                widget.onBarTap?.call(data);
                _selectDate = date;
                setState(() {});
              },
              child: Container(
                  alignment: Alignment.center,
                  child: Container(
                    width: 6.0,
                    height: _maxValue > 0 ? data * (200 / _maxValue) : 0,
                    margin: EdgeInsets.only(
                        top: _maxValue > 0
                            ? (200 - data * (200 / _maxValue))
                            : 0,
                        bottom: 0),
                    decoration: BoxDecoration(
                      color: date == _selectDate
                          ? Color(color).withOpacity(0.5)
                          : Color(color),
                      borderRadius: const BorderRadius.vertical(
                        top: Radius.circular(20.0),
                      ),
                    ),
                  )),
            )));
  }

  ///构建条形颜色
  Widget _buildDrawColor({required int index, required int color}) {
    return BaseViewItem(
        weight: 1,
        child: Container(
          height: 4,
          decoration: BoxDecoration(
            color: Color(color),
            borderRadius: BorderRadius.only(
                topRight:
                    Radius.circular(index == _dayDataList.length - 1 ? 20 : 0),
                bottomRight:
                    Radius.circular(index == _dayDataList.length - 1 ? 20 : 0)),
          ),
        ));
  }

  ///构建日期
  Widget _buildDrawDate({required String date}) {
    return BaseViewItem(
        weight: 1,
        child: Text(
          date,
          textAlign: TextAlign.center,
          style: ThemeUtil.p2.copyWith(
              fontSize: 8, color: const Color(ThemeUtil.primaryWhiteValue50)),
        ));
  }

  ///构建排卵日
  Widget _buildOvulationDay({required bool isOvulation}) {
    return BaseViewItem(
        weight: 1,
        child: isOvulation
            ? const Image(
                image: AssetImage(ImageRes.ic_main_ovulation),
                width: 8,
                height: 8,
              )
            : const SizedBox(
                width: 8,
                height: 8,
              ));
  }

  ///判断是否是排卵日
  bool _isOvulationDay(DateTime dateTime) {
    if(widget.periodDataMap.isNotEmpty && widget.periodDataMap[DateFormat("yyyy-MM-dd").format(dateTime)] != null){
      if(widget.periodDataMap[DateFormat("yyyy-MM-dd").format(dateTime)] == 4){
        return true;
      }
      return false;
    }
    if (_menstrualTime <= 0) {
      return false;
    }
    if (!_isShowOvulation) {
      return false;
    }
    int differenceDay = _calculateDaysDifference(_ovulationDateTime, dateTime);
    if (differenceDay != 0 && differenceDay % _cycleValue == 0) {
      return true;
    }
    if (DateFormat("yyyy-MM-dd").format(_ovulationDateTime) == DateFormat("yyyy-MM-dd").format(dateTime)) {
      return true;
    }
    return false;
  }

  /// 计算两个 DateTime 对象相差的天数
  int _calculateDaysDifference(DateTime startDate, DateTime endDate) {
    return (startDate.difference(endDate).inDays).abs();
  }

  ///获取不一样月份
  String _getDifferentMonth() {
    int month = _parseYmdDate(_dayDataList[0]).month;
    for (int i = 1; i < _dayDataList.length; i++) {
      if (_parseYmdDate(_dayDataList[i]).month != month) {
        return StringUtil.getTodayMonth(_parseYmdDate(_dayDataList[i]).month);
      }
    }
    return "";
  }

  ///获取不一样月份下标
  int _getDifferentMonthIndex() {
    int month = _parseYmdDate(_dayDataList[0]).month;
    for (int i = 1; i < _dayDataList.length; i++) {
      if (_parseYmdDate(_dayDataList[i]).month != month) {
        return i;
      }
    }
    return 0;
  }

  ///获取当前柱状图的背景色
  int _getBarBackgroundColor(DateTime dateTime) {
    if (_menstrualTime <= 0) {
      return ThemeUtil.primarTransparentValue;
    }
    if(widget.periodDataMap.isNotEmpty && widget.periodDataMap[DateFormat("yyyy-MM-dd").format(dateTime)] != null){
      int type = widget.periodDataMap[DateFormat("yyyy-MM-dd").format(dateTime)]!;
      if(type == 1 || type == 6 || type == 7){
        return ThemeUtil.primarPredictionValue;
      }
      if(type == 2){
        return ThemeUtil.primarFollicularValue;
      }
      if(type == 3 || type == 8 || type == 9){
        return ThemeUtil.primarMainPregnancyValue;
      }
      if(type == 4){
        return ThemeUtil.primarOvulationValue;
      }
      if(type == 5){
        return ThemeUtil.primarLutealValue;
      }
      if(type == 0){
        if(_follicularPhaseDays >0 ){
          return ThemeUtil.primarFollicularValue; // 卵泡期
        }else if(_follicularPhaseDays == 0 && _easyPregnancyDays > 0){
          return ThemeUtil.primarMainPregnancyValue; // 易孕期
        }else if(_follicularPhaseDays == 0 && _easyPregnancyDays == 0 && _lutealPhaseDays > 0){
          return ThemeUtil.primarLutealValue; // 黄体期
        }
      }
    }

    if (_isOvulationDay(dateTime)) {
      return ThemeUtil.primarOvulationValue;
    }
    DateTime lastMenstrualDate = DateTime.fromMillisecondsSinceEpoch(_menstrualTime);
    if (dateTime.millisecondsSinceEpoch < _menstrualTime) {
      lastMenstrualDate = lastMenstrualDate.subtract(Duration(days: _cycleValue));
    }
    int differenceDay = (((dateTime.difference(lastMenstrualDate).inDays).abs()) % _cycleValue) + 1;
    if (differenceDay <= _menstrualPeriodDays) {
      return ThemeUtil.primarPredictionValue; //月经期
    } else if (differenceDay <= _menstrualPeriodDays + _follicularPhaseDays) {
      return ThemeUtil.primarFollicularValue; // 卵泡期
    } else if (differenceDay <= _menstrualPeriodDays + _follicularPhaseDays + _easyPregnancyDays) {
      return ThemeUtil.primarMainPregnancyValue; // 易孕期
    } else if (differenceDay <= _menstrualPeriodDays + _follicularPhaseDays + _easyPregnancyDays + _lutealPhaseDays) {
      return ThemeUtil.primarLutealValue; // 黄体期
    }
    return ThemeUtil.primarPredictionValue;
  }

}
